//
// Created by htlin on 2021/3/5 0005.
//

#include "ThreadAsync.h"

#include <memory>

class ThreadAsyncPrivateData {
public:
    uv_loop_t *loop;
    uv_async_t async;
    ThreadAsyncData *threadAsyncData;
    ThreadAsync::AsyncCallback asyncCallback;
};

ThreadAsync::ThreadAsync(uv_loop_t *loop, ThreadAsyncData *threadAsyncData) {
  data = std::make_unique<ThreadAsyncPrivateData>();
  data->threadAsyncData = threadAsyncData;
  data->loop = loop;
}

ThreadAsync::~ThreadAsync() {
  delete data->threadAsyncData;
  if (nullptr != data->async.loop) {
    uv_close((uv_handle_t *) &data->async, nullptr);
  }
}

void ThreadAsync::setAsyncCB(ThreadAsync::AsyncCallback asyncCallback) {
  data->asyncCallback = asyncCallback;
  int res = uv_async_init(data->loop, &data->async, ThreadAsync::asyncCB);
  res = 1;
}

ThreadAsyncData *ThreadAsync::getThreadAsyncData() {
  return data->threadAsyncData;
}

void ThreadAsync::asyncCB(uv_async_t *data) {
  auto thisPointer = static_cast<ThreadAsync *>(data->data);
  if (nullptr != thisPointer->data->asyncCallback) {
    thisPointer->data->asyncCallback(thisPointer->data->threadAsyncData);
  }
}

void ThreadAsync::sendAsync(void *data) {
  this->data->threadAsyncData->setSubData(data);
  this->data->async.data = static_cast<void *>(this);
  uv_async_send(&this->data->async);
}
